package com.example.demo.service.security;

import com.example.demo.common.enums.StaticValues;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.impl.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Author: ak
 * @Date: 2020/4/1 23:26
 */
@Slf4j
public class CustomRealm extends AuthorizingRealm {
    @Autowired
    UserServiceImpl userService;
    @Autowired
    UserMapper userMapper;

    private PermissionManger permissionManger = new PermissionManger();

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("开启权限认证-----------");
        //获取用户信息
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //获取角色信息和角色权限，进行授权
        if (user.getRoleSet().size() == 0) {
            log.info("无权限");
            return info;
        }
        for (Role role : user.getRoleSet()) {
            log.info("用户角色" + role.getRoleName());
            info.addRole(role.getRoleName());
            for (Permission permission : role.getPermissionSet()) {
                info.addStringPermission(permission.getPermissionName());
                log.info("用户权限" + permission.getPermissionName());
            }
        }
        return info;
    }

    /**
     * 获取即将需要认证的信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("开启资源认证-----------");
        //获取从页面拿到的用户名
        UsernamePasswordToken userLoginMsg = (UsernamePasswordToken) authenticationToken;
        String userName = userLoginMsg.getUsername();
        //根据用户名从数据库获取密码,如果用户名不存在则抛出异常，此处逻辑省略
        User user = userMapper.findeUserByUserName(userName);
        addPermit(user);
        //用户名判断
        if (userName == null) {
            return null;
        }
        //密码判断,principal用于存储用户信息
        return new SimpleAuthenticationInfo(user, user.getUPassword(), getName());
    }

    /**
     * 权限初始化
     *
     * @param user 需要初始化权限的用户
     */
    private void addPermit(User user) {
        Role role = permissionManger.getRole(user.getURole());
        //如果是管理员，额外添加用户权限
        if (user.getURole().equals(StaticValues.ADMIN)) {
            user.addRole(permissionManger.getUser());
        }
        user.addRole(role);
    }
}
